package cn.iphone.NPlayer.service.impl;

import cn.iphone.NPlayer.CourseDoc;
import cn.iphone.NPlayer.constants.MqConstants;
import cn.iphone.NPlayer.domain.*;
import cn.iphone.NPlayer.dto.CourseDto;
import cn.iphone.NPlayer.dto.MessageSmsDto;
import cn.iphone.NPlayer.dto.UserSmsDto;
import cn.iphone.NPlayer.exception.GlobalExceptionCodeEnum;
import cn.iphone.NPlayer.fegin.CourseEsService;
import cn.iphone.NPlayer.mapper.CourseMapper;
import cn.iphone.NPlayer.mapper.CourseTypeMapper;
import cn.iphone.NPlayer.result.JSONResult;
import cn.iphone.NPlayer.service.*;
import cn.iphone.NPlayer.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ikun
 * @since 2022-11-22
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private ICourseDetailService courseDetailService;
    @Autowired
    private ICourseMarketService courseMarketService;
    @Autowired
    private ICourseResourceService courseResourceService;
    @Autowired
    private ICourseSummaryService courseSummaryService;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private CourseEsService courseEsService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void save(CourseDto courseDto) {
        // 0.取值
        Course course = courseDto.getCourse();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        CourseResource courseResource = courseDto.getCourseResource();
        List<Long> teacherIds = courseDto.getTeacherIds();
        // 1.JSR303校验

        // 2.断言此课程是否存在，根据课程名称判断
        Course courseName = selectByName(course.getName());
        AssertUtil.isNull(courseName, GlobalExceptionCodeEnum.COURSE_EXIST_ERROR);

        // 3.保存课程表
        Long courseId = saveCourse(course, teacherIds);

        // 4.保存课程详情表
        saveCourseDetail(courseDetail, courseId);

        // 5.保存课程销售表
        saveCourseMarket(courseMarket, courseId);

        // 6.保存课程资源表
        saveCourseResource(courseResource, courseId);

        // 7.初始化课程统计表
        initCourseSummary(courseId);

        // 8.初始化课程讲师中间表
        courseMapper.initCourseTeacher(courseId, teacherIds);




    }

    @Override
    public void onLineCourse(Long courseId) {
        // 1.参数校验
        // 2.业务校验
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course, GlobalExceptionCodeEnum.COURSE_NOT_EXIST);
        // 3.修改状态
        course.setStatus(Course.ON_LINE);
        course.setOnlineTime(new Date());
        updateById(course);
        // 4.保存coursedoc数据
        // 4.1 查询数据
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
        CourseMarket courseMarket = courseMarketService.selectById(course.getId());
        CourseSummary courseSummary = courseSummaryService.selectById(course.getId());
        // 4.2 拷贝数据导coursedoc中
        CourseDoc courseDoc = new CourseDoc();
        BeanUtils.copyProperties(course, courseDoc);
        BeanUtils.copyProperties(courseType, courseDoc);
        BeanUtils.copyProperties(courseMarket, courseDoc);
        BeanUtils.copyProperties(courseSummary, courseDoc);
        // 4.3 单独保存的字段
        courseDoc.setName(course.getName());
        courseDoc.setCourseTypeName(courseType.getName());
        courseDoc.setCharge(courseMarket.getCharge() == 1 ? "收费" : "免费");
        // 5.调用fegin接口保存
        JSONResult jsonResult = courseEsService.saveCourseEs(courseDoc);
        // 6.发布失败抛出异常
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCodeEnum.COURSE_PUBLISH_ERROR);
        // 7.MQ推送消息
        sendMessage(courseDoc);

    }

    @Override
    public void offLineCourse(Long courseId) {
        // 1.校验
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course, GlobalExceptionCodeEnum.COURSE_NOT_EXIST);
        AssertUtil.isFalse(course.getStatus().equals(Course.OFF_LINE), GlobalExceptionCodeEnum.COURSE_ALREADY_OFFLINE);
        // 2.修改状态
        course.setStatus(Course.OFF_LINE);
        updateById(course);
        // 3.删除ES的数据
        JSONResult jsonResult = courseEsService.offLineCourse(courseId);
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCodeEnum.COURSE_OFFLINE_ERROR);
    }

    private void sendMessage(CourseDoc courseDoc) {
        MessageSmsDto messageSmsDto = new MessageSmsDto();
        messageSmsDto.setTitle("课程发布");
        messageSmsDto.setContent("亲爱的用户您好，最新课程 <a href='localhost:6002/list.html?courseId="+courseDoc.getId()+"'> 测试 </a> 发布啦，点击课程了解详情");
        List<UserSmsDto> userSmsDtos = Arrays.asList(new UserSmsDto(1L, "19988886666"), new UserSmsDto(2L, "19988887777"));
        messageSmsDto.setUsers(userSmsDtos);
        rocketMQTemplate.sendOneWay(MqConstants.COURSE_SMS_TOPIC + ":" + MqConstants.COURSE_SMS_TAG, JSON.toJSONString(messageSmsDto));
    }

    private void initCourseSummary(Long courseId) {
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(courseId);
        courseSummaryService.insert(courseSummary);
    }

    private void saveCourseResource(CourseResource courseResource, Long courseId) {
        courseResource.setCourseId(courseId);
        courseResourceService.insert(courseResource);
    }

    private void saveCourseMarket(CourseMarket courseMarket, Long courseId) {
        courseMarket.setId(courseId);
        courseMarketService.insert(courseMarket);
    }

    private void saveCourseDetail(CourseDetail courseDetail, Long courseId) {
        courseDetail.setId(courseId);
        courseDetailService.insert(courseDetail);
    }

    private Long saveCourse(Course course, List<Long> teacherIds) {
        course.setStatus(Course.OFF_LINE);
        course.setLoginId(1L);
        String teacherNames = teacherService.selectBatchIds(teacherIds).stream().map(Teacher::getName).collect(Collectors.joining(","));
        course.setTeacherNames(teacherNames);
        insert(course);
        return course.getId();
    }

    private Course selectByName(String name) {
        Wrapper<Course> wrapper = new EntityWrapper<>();
        wrapper.eq("name", name);
        return selectOne(wrapper);
    }
}
